import DataBase from "@/DataBase";
import ObjectTemplateUtil from "@/ObjectTemplateUtil";
import LangUtil from "@/LangUtil";
import STimer from "@/STimer";


let index = 0;
/**
 * 基础的演员 数据结构
 * 演员 是模拟系统的 具体解决方案 可以通过演员方面的模拟技能 物品 以抽取出统一的方法和数据结构
 *
 * 每一个 物品/技能演员实例都对应一个唯一的基础物编模板 即相同演员类型的多个演员物品获取到的原始物品模板id也是不同的。
 *
 * 单位演员多个实例都是公用一个类型的。
 *
 * 为保证物编模板足够使用 需要在演员实例不需要使用时进行销毁 这样会把占用的物编模板id归还以供下次新建演员实例使用
 *
 */
export default class Actor {
    static templateIdActorMap: { [templateId: string]: any } = {}

    readonly uuid: string = "sa" + index++;
    /**可以为 技能模板id 物品模板id 单位模板id*/
    templateId: string
    actorType: AppActorType;
    /** 关联的单位 */
    private _unit?: unit

    /** 战斗属性  */
    attribute?: AppAttribute;

    /** 部分被动技能需要的循环计时器 */
    sTimer?: STimer
    /** 预制特效变量 */
    effect?: effect

    /** 数据 */
    data: { [key: string]: any } = {};

    /** 自定义任意数据 */
    [key: string]: any;

    //
    private _sl_isInitialized = false;


    constructor(actorTypeId?: string) {
        if (actorTypeId == null) {
            this.actorType = {} as any
        } else {
            this.actorType = DataBase.getSolarActorType(actorTypeId);
        }
        if (this.actorType.attribute) {
            this.attribute = {...this.actorType.attribute}
        }
    }

    /**
     * 将类型中的模板数据设置到实例中
     */
    init() {
        if (this._sl_isInitialized) {
            return
        }
        this._sl_isInitialized = true;
        for (let key in this.actorType) {
            let value = this.actorType[key];
            if (LangUtil.isString(value) || LangUtil.isNumber(value)) {
                this.set(key, value)
            }
        }
        this.get("onCreated")?.(this);
        if (this.templateId != null) {
            Actor.templateIdActorMap[this.templateId] = this;
        }
    }


    get solarData(): AppSolarBuffData {
        return DataBase.getSolarActorSolarData(this.uuid)
    }

    set solarData(obj: { [key: string]: any }) {
        DataBase.setSolarActorSolarData(this.uuid, obj)
    }


    set<Key extends keyof AppActorType>(key: Key, value: AppActorType[Key]): void {
        this.data[key] = value;
    }

    get<Key extends keyof AppActorType>(key: Key, defaultValue?: AppActorType[Key]): AppActorType[Key] {
        if (this.data[key] != null) {
            return this.data[key] as any
        }
        if (this.actorType?.[key] != null) {
            return this.actorType[key]
        }
        return defaultValue;
    }

    /**
     * 刷新
     */
    refresh() {
        //重新
        for (let dataKey in this.data) {
            this.set(dataKey, this.data[dataKey])
        }
        this.get("onRefresh")?.(this);
    }

    /**
     * 获取类型id
     */
    getActorTypeId(): string {
        return this.actorType.id
    }

    /**
     * 获取模板类型
     */
    getTemplateType(): string {
        return this.get("templateType")
    }


    get unit(): unit {
        return this._unit;
    }

    set unit(value: unit) {
        this._unit = value;
        this.get("onUnitChange")?.(this, value)
    }

    /**
     * 设置名字
     * @param name
     */
    setName(name: AppActorType["name"]) {
        this.set("name", name)
    }

    getName(): string {
        return this.get("name")
    }

    /**
     * 设置图标
     * @param icon
     */
    setIcon(icon: AppActorType["icon"]) {
        this.set("icon", icon)
    }

    getIcon(): string {
        return this.get("icon")
    }

    /**
     * 设置描述
     * @param describe
     */
    setDescribe(describe: AppActorType["describe"]) {
        this.set("describe", describe)
    }

    getDescribe(): string {
        return this.get("describe")
    }


    setDisable(disable: AppActorType["disable"]) {
        this.set("disable", disable)
    }

    isDisable(): boolean {
        return this.get("disable", false)
    }


    /**
     * 设置xy位置
     */
    setXY(x: number, y: number): void {
        this.set("x", x)
        this.set("y", y)
    }

    /**
     * 获取xy位置
     */
    getXY(): Vector {
        return {x: this.get("x"), y: this.get("y")}
    }


    setHide(hide: boolean) {
        this.set("hide", hide)
    }

    isHide(): boolean {
        return this.get("hide", false)
    }


    clone(): void {

    }

    localClick(data?: any): boolean {
        isAsync = true;
        let b = this.get("onLocalClick")?.(this, data);
        isAsync = false;
        if (b == false) {
            return false;
        }
        return true;
    }

    action(data?: any) {
        this.get("onAction")?.(this, data);
    }

    /**
     * 销毁此actor
     */
    destroy(): void {
        this.get("onDestroy")?.(this);
        Actor.templateIdActorMap[this.templateId] = null;
        if (this.getTemplateType() != null) {
            ObjectTemplateUtil.returnTemplate(this.getTemplateType(), this.templateId);
        }

    }


    public static getByTemplateId<T extends Actor>(templateId: string): T {
        return Actor.templateIdActorMap[templateId];
    }

}